Освойте CSS Custom Highlight API для управления выделением текста. Создавайте пользовательские стили, управляйте диапазонами и стройте динамичные UI с беспрецедентной гибкостью.
API пользовательских выделений CSS: Освоение многодиапазонного выделения текста для динамичных пользовательских интерфейсов
API пользовательских выделений CSS – это новый мощный инструмент для веб-разработчиков, который обеспечивает беспрецедентный контроль над выделением и подсветкой текста в веб-приложениях. В отличие от базовых возможностей выделения в браузере, этот API позволяет разработчикам определять пользовательские стили выделения и программно управлять несколькими диапазонами выделения. Это открывает мир возможностей для создания насыщенных, интерактивных и доступных пользовательских интерфейсов. Данное руководство предоставляет всесторонний обзор API, исследуя его возможности, варианты использования и детали реализации, все с глобальной перспективой.
Понимание основ API пользовательских выделений CSS
Прежде чем погружаться в сложные сценарии, важно усвоить фундаментальные концепции API. По своей сути, API пользовательских выделений CSS вводит несколько новых псевдоэлементов CSS, в том числе:
::selection: Представляет часть документа, которая была выделена пользователем. Этот элемент давно доступен, позволяя базовое стилизование выделений текста.::highlight: Более общий псевдоэлемент для применения стилей к выделенным диапазонам. Это ключ к мощи нового API. Теперь вы можете создавать именованные выделения и применять к каждому из них пользовательские стили.::target-text: Представляет часть документа, на которую указывает фрагмент URI (например,#section-title). Он позволяет стилизовать раздел страницы, к которому пользователь прокрутил с помощью ссылки.::spelling-error: Представляет текст, идентифицированный пользовательским агентом как содержащий орфографические ошибки. Предлагает контроль стилизации индикаторов орфографических ошибок.::grammar-error: Представляет текст, идентифицированный пользовательским агентом как содержащий грамматические ошибки. Предлагает контроль стилизации индикаторов грамматических ошибок.
Псевдоэлемент ::highlight является основной рабочей лошадкой API. Он позволяет определять именованные выделения в CSS, а затем применять эти выделения к определенным диапазонам текста с помощью JavaScript.
Ключевые концепции: Диапазоны и выделения
API строится вокруг концепций диапазонов и выделений:
- Диапазон: Смежная часть текста в документе. Представляется объектом
Rangeв JavaScript. - Выделение: Именованный стиль, применяемый к одному или нескольким диапазонам. Определяется в CSS с использованием псевдоэлемента
::highlight(highlight-name)и управляется через APIHighlightиHighlightRegistryв JavaScript.
Думайте об этом так: диапазон — это «что» (текст, который вы хотите выделить), а выделение — это «как» (стиль, который вы хотите применить).
Настройка пользовательских выделений с помощью CSS
Первый шаг — определить ваши пользовательские стили выделения в CSS. Вы делаете это с помощью псевдоэлемента ::highlight().
::highlight(search-result) {
background-color: yellow;
color: black;
}
::highlight(important-term) {
background-color: lightblue;
font-weight: bold;
}
В этом примере мы определили два пользовательских стиля выделения: search-result и important-term. Выделение search-result применит желтый фон с черным текстом, а выделение important-term будет использовать светло-голубой фон и сделает текст жирным. Вы можете определить любые свойства CSS, которые хотите, в этих стилях выделения.
Управление выделениями с помощью JavaScript
После того как вы определили стили выделения в CSS, вы можете использовать JavaScript для их применения к определенным диапазонам текста. API Highlight и HighlightRegistry предоставляют для этого инструменты.
HighlightRegistry
HighlightRegistry — это глобальный объект, который управляет всеми выделениями в документе. Вы можете получить к нему доступ через интерфейс CSS:
const highlightRegistry = CSS.highlights;
Создание выделений
Для создания выделения используется конструктор Highlight:
const highlight = new Highlight();
Изначально выделение не имеет связанных с ним диапазонов. Вам нужно добавить диапазоны к выделению с помощью метода addRange().
Добавление диапазонов к выделению
Чтобы добавить диапазон к выделению, сначала нужно создать объект Range. Вы можете сделать это с помощью метода document.createRange():
const range = document.createRange();
range.setStart(startNode, startOffset);
range.setEnd(endNode, endOffset);
highlight.addRange(range);
Где:
startNode: DOM-узел, где начинается диапазон.startOffset: Смещение символов внутриstartNode, где начинается диапазон.endNode: DOM-узел, где заканчивается диапазон.endOffset: Смещение символов внутриendNode, где заканчивается диапазон.
Пример: Выделение результатов поиска
Допустим, у вас есть блок текста, и вы хотите выделить все вхождения поискового запроса. Вот как это можно сделать:
function highlightSearchResults(searchTerm, element) {
const text = element.textContent;
let index = text.indexOf(searchTerm);
if (index === -1) {
return; // Search term not found
}
const highlight = new Highlight();
while (index !== -1) {
const range = document.createRange();
range.setStart(element.firstChild, index);
range.setEnd(element.firstChild, index + searchTerm.length);
highlight.addRange(range);
index = text.indexOf(searchTerm, index + 1);
}
// Apply the 'search-result' highlight style
highlightRegistry.set('search-result', highlight);
}
const contentElement = document.getElementById('content');
highlightSearchResults('example', contentElement);
Этот фрагмент кода находит все вхождения слова «example» в элементе с ID «content» и применяет к ним стиль выделения search-result.
Удаление диапазонов и выделений
Вы можете удалить диапазоны из выделения с помощью метода deleteRange():
highlight.deleteRange(range);
Вы также можете удалить все диапазоны из выделения с помощью метода clear():
highlight.clear();
Чтобы полностью удалить выделение, вы можете использовать метод delete() из HighlightRegistry:
highlightRegistry.delete('search-result');
Расширенные варианты использования и соображения
API пользовательских выделений CSS — это мощный инструмент, который может использоваться в различных продвинутых сценариях.
Совместное редактирование
В приложениях для совместного редактирования вы можете использовать API для выделения изменений, сделанных разными пользователями. Каждый пользователь может иметь свой собственный стиль пользовательского выделения, что позволяет легко видеть, кто и какие изменения внес. Например, редактор совместных документов, используемый командами в нескольких странах, может использовать разные цвета выделения для обозначения правок от членов команды из Японии, Германии и Бразилии.
Редакторы кода
Редакторы кода могут использовать API для подсветки синтаксиса. Различные элементы синтаксиса (например, ключевые слова, операторы, комментарии) могут быть назначены различным стилям выделения. Современные редакторы кода часто имеют сложные правила подсветки синтаксиса, и этот API позволяет более точный и настраиваемый контроль, чем традиционные методы.
Доступность
API может использоваться для улучшения доступности. Например, вы можете выделить текущий сфокусированный элемент или текст, который читает программа чтения с экрана. Не забывайте обеспечивать достаточный контраст между фоном выделения и цветом текста для пользователей с нарушениями зрения. WCAG (Руководство по доступности веб-контента) предоставляет конкретные рекомендации по коэффициентам цветового контраста.
Соображения по интернационализации (i18n)
При использовании API в многоязычных приложениях учитывайте следующее:
- Направление текста: Убедитесь, что ваши стили выделения корректно работают как с языками с направлением письма слева направо (LTR), так и справа налево (RTL).
- Границы слов: Разные языки имеют разные правила для границ слов. Обязательно используйте соответствующие алгоритмы обнаружения границ слов при выделении слов или фраз.
- Наборы символов: API поддерживает Unicode, поэтому вы можете выделять текст на любом языке.
Например, при выделении поисковых запросов на арабском языке (язык RTL) убедитесь, что выделение визуально отражает правильное направление текста. Аналогично, при выделении ключевых слов на японском языке, где не используются пробелы между словами, вам потребуется использовать соответствующий морфологический анализ для определения границ слов.
Соображения по производительности
Хотя API является мощным, важно помнить о производительности. Создание и управление большим количеством выделений может повлиять на производительность, особенно в больших документах. Учитывайте следующие советы:
- Оптимизируйте создание диапазонов: Создание объектов
Rangeможет быть ресурсоемким. По возможности повторно используйте существующие диапазоны. - Пакетные обновления: При внесении нескольких изменений в выделения объединяйте их в одно обновление, чтобы минимизировать перерисовку.
- Ленивая загрузка: Выделяйте только тот текст, который в данный момент виден пользователю. Загружайте дополнительные выделения по мере прокрутки пользователем.
- Виртуализация: Для очень больших документов рассмотрите возможность использования методов виртуализации для рендеринга только видимой части документа.
Практические примеры и фрагменты кода
Пример 1: Динамическая подсветка ключевых слов
Этот пример демонстрирует, как динамически выделять ключевые слова в тексте на основе ввода пользователя. Представьте, что пользователь вводит поисковый запрос в поле поиска; выделенные ключевые слова обновляются в реальном времени.
This is some example text. It contains keywords that we want to highlight. We will highlight the keywords based on user input.
const keywordInput = document.getElementById('keyword-input');
const textContainer = document.getElementById('text-container');
keywordInput.addEventListener('input', () => {
const keyword = keywordInput.value.trim();
if (keyword) {
highlightKeyword(keyword, textContainer);
} else {
clearHighlights(textContainer);
}
});
function highlightKeyword(keyword, element) {
clearHighlights(element);
const text = element.textContent;
let index = text.indexOf(keyword);
if (index === -1) {
return;
}
const highlight = new Highlight();
while (index !== -1) {
const range = document.createRange();
range.setStart(element.firstChild, index);
range.setEnd(element.firstChild, index + keyword.length);
highlight.addRange(range);
index = text.indexOf(keyword, index + 1);
}
CSS.highlights.set('dynamic-keyword', highlight);
}
function clearHighlights(element) {
CSS.highlights.delete('dynamic-keyword');
}
::highlight(dynamic-keyword) {
background-color: rgba(255, 165, 0, 0.5); /* Semi-transparent orange */
color: black;
}
Пример 2: Реализация функции «Найти все»
Этот пример имитирует функцию «Найти все», аналогичную тем, что встречаются в текстовых редакторах и IDE. Все вхождения поискового запроса выделяются одновременно.
This document contains multiple instances of the search term. The search term will be highlighted throughout the document.
This is a second instance of the search term. Here's another search term.
const searchTermInput = document.getElementById('search-term');
const documentContent = document.getElementById('document-content');
searchTermInput.addEventListener('input', () => {
const searchTerm = searchTermInput.value.trim();
if (searchTerm) {
findAll(searchTerm, documentContent);
} else {
clearFindAllHighlights(documentContent);
}
});
function findAll(searchTerm, element) {
clearFindAllHighlights(element);
const text = element.textContent;
let index = text.indexOf(searchTerm);
const highlight = new Highlight();
while (index !== -1) {
const range = document.createRange();
range.setStart(element.firstChild, index);
range.setEnd(element.firstChild, index + searchTerm.length);
highlight.addRange(range);
index = text.indexOf(searchTerm, index + 1);
}
CSS.highlights.set('find-all', highlight);
}
function clearFindAllHighlights(element) {
CSS.highlights.delete('find-all');
}
::highlight(find-all) {
background-color: #90EE90; /* LightGreen */
color: black;
}
Совместимость с браузерами и полифиллы
API пользовательских выделений CSS — относительно новая функция, поэтому совместимость с браузерами может варьироваться. По состоянию на конец 2024 года, она хорошо поддерживается в современных браузерах, таких как Chrome, Firefox, Safari и Edge. Однако важно проверять последние данные о совместимости браузеров на таких сайтах, как «Can I use...», чтобы убедиться, что ваша целевая аудитория может использовать ваши функции. Если вам нужна поддержка более старых браузеров, вы можете изучить полифиллы или альтернативные подходы, которые имитируют функциональность API, хотя они могут не предлагать такой же уровень производительности или точности.
Будущее выделения текста
API пользовательских выделений CSS представляет собой значительный шаг вперед в веб-разработке, предоставляя разработчикам гранулярный контроль над выделением текста. По мере созревания API и улучшения поддержки браузерами, мы можем ожидать еще более инновационного использования этой технологии. От продвинутых текстовых редакторов до платформ для совместной работы над документами, возможности безграничны. Этот API позволяет создать более богатый, интерактивный и доступный пользовательский опыт. Подумайте, как это можно использовать для улучшения пользовательского опыта во всем: от международных новостных сайтов до онлайн-платформ для изучения языков.
Заключение
API пользовательских выделений CSS — мощный инструмент для создания динамичных и интерактивных пользовательских интерфейсов. Понимая базовые концепции диапазонов, выделений и HighlightRegistry, вы можете использовать этот API для создания увлекательных пользовательских интерфейсов, которые ранее было трудно или невозможно реализовать. Исследуя этот API, не забывайте учитывать доступность, интернационализацию и производительность, чтобы ваши приложения были удобными и высокопроизводительными для глобальной аудитории. Благодаря своей гибкости и контролю, API пользовательских выделений CSS готов стать неотъемлемой частью инструментария современного веб-разработчика.